package com.mzw.huaxiarealestatebackend.controller;

import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.secure.SaSecureUtil;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;

import com.mzw.huaxiarealestatebackend.common.utils.DataResult;
import com.mzw.huaxiarealestatebackend.common.utils.DateFormat;
import com.mzw.huaxiarealestatebackend.dao.UserDao;
import com.mzw.huaxiarealestatebackend.dto.UserDTO;
import com.mzw.huaxiarealestatebackend.entity.User;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Objects;


@Api(tags = "用户登录")
@Slf4j
@RestController
@RequestMapping("/api/user")
@CrossOrigin
@SaIgnore
public class LoginController {

    @Autowired
    private UserDao userMapper;

    @Value("${mzw.password-key}")
    private String passwordKey;

    public String code;

    // 用来生成验证码的接口，HttpServletResponse 用于将生成的验证码响应到页面展示
    @ApiOperation("获取图片验证码")
    @GetMapping("/getVCode")
    public void getCode(HttpServletResponse response) {
        // HuTool定义图形验证码的长和宽,验证码的位数，干扰线的条数
        // 验证码工具类
        LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(120, 45, 4, 80);
        code = lineCaptcha.getCode();
        response.setContentType("image/jpeg");
        try {
            ServletOutputStream outputStream = response.getOutputStream();
            lineCaptcha.write(outputStream);
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @ApiOperation("校验图片验证码")
    @PostMapping("/check/code/{Vcode}")
    public DataResult checkVcode(@PathVariable String Vcode) {
        if (!StrUtil.equals(Vcode, code)) {
            return DataResult.failure("验证码错误 请重新输入");
        } else {
            return DataResult.ok();
        }
    }

    @ApiOperation("登录(需输入验证码)")
    @PostMapping("/login/{Vcode}")
    public DataResult doLogin(@RequestBody User user, @PathVariable(value = "Vcode") String Vcode) {
        // 验证
        if (!StrUtil.equals(Vcode, code)) {
            return DataResult.failure("验证码错误 请重新输入");
        }
        else {
            // 密码加密后与数据库密码做对比
            String ciphertext = SaSecureUtil.aesEncrypt(passwordKey, user.getUserPassword());
            User loginUser = userMapper.selectNameAndPassword(user.getUserName(), ciphertext);
            if (Objects.isNull(loginUser)) {
                return DataResult.failure("用户名或者密码错误");
            } else {
                // 根据账号id，进行登录 => 此处id为用户名
                StpUtil.login(user.getUserName(), new SaLoginModel()
                                // Token挂载的扩展参数
                                .setExtra("username", loginUser.getUserName())
                                .setExtra("uid", loginUser.getUserId())
                                .setExtra("email", loginUser.getUserEmail())
                                .setExtra("role", loginUser.getUserRole())
                                .setIsWriteHeader(true)
                                // 设置token过期时间 1 小时
                                .setTimeout(60 * 60 * 1 )
                );
                // 更新用户登录时间
                userMapper.updateLoginTime(loginUser.getUserId(), DateFormat.getNowDateFormat());
                // 将loginUser转化成UserDTO
                UserDTO userDTO = BeanUtil.copyProperties(loginUser, UserDTO.class);
                HashMap<Object, Object> res = new HashMap<>();
                res.put("userDTO", userDTO);
                res.put("HREtoken", StpUtil.getTokenInfo());
                return new DataResult(200, "登录成功", res);
            }
        }
    }


    /**
     * <h2>退出登录
     */
    @ApiOperation("退出登录")
    @PostMapping("/logout")
    public DataResult logout() {
        StpUtil.logout();
        return DataResult.ok("退出登录成功");
    }

    /**
     * <h2>查看登录会话是否登录
     */
    @ApiOperation("验证是否登录")
    @GetMapping("/is-login")
    public DataResult isLogin() {
        // 查看当前会话是否登录
        boolean isLogin = StpUtil.isLogin();
        return new DataResult(isLogin ? 200 : 403, isLogin ? "用户已经登录" : "用户未登录无权操作");
    }


}
